package com.ctg.itrdc.imageconsole.util;

import java.text.MessageFormat;
import java.util.Map;
import java.util.TreeMap;

import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.json.JSONArray;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ctg.itrdc.imageconsole.data.dto.user.UserDTO;

/**
 * 		Author			Date			Operation
 * 		Shizhu.Peng		2017-03-25		create
 */

public class HarborUtil {	

	private final static String USERSURLTEMPLATE = "http://{0}/api/users";
	
	private final static String USERSUSERIDPASSWORDURLTEMPLATE = "http://{0}/api/users/{1}/password";
	
	private final static String USERSUSERIDURLTEMPLATE = "http://{0}/api/users/{1}";
	
	private final static String PROJECTSURLTEMPLATE = "http://{0}/api/projects";
	
	private final static String PROJECTSPROJECTIDURLTEMPLATE = "http://{0}/api/projects/{1}";
	
	private final static String TARGETSURLTEMPLATE = "http://{0}/api/targets";
	
	private final static String POLICIESREPLICATIONURLTEMPLATE = "http://{0}/api/policies/replication";
	
	private final static String POLICIESREPLICATIONIDENABLEMENTURLTEMPLATE = "http://{0}/api/policies/replication/{1}/enablement";
	
	private final static String REPOSITORIESURLTEMPLATE = "http://{0}/api/repositories";
	
	private final static String REPOSITORIESTAGSURLTEMPLATE = "http://{0}/api/repositories/tags";
	
	private static Logger logger = LoggerFactory.getLogger(HarborUtil.class);
	
	public static Integer updatePasswordByUserId(String harbor, String token, Long userId, String oldPassword, String newPassword) {
		// url
		String usersUserIdPasswordUrl = MessageFormat.format(HarborUtil.USERSUSERIDPASSWORDURLTEMPLATE, harbor, userId);
		
		// put body
		Map<String, Object> password = new TreeMap<>();
		password.put("old_password", oldPassword);
		password.put("new_password", newPassword);
		WebTarget target = ClientBuilder.newClient().target(usersUserIdPasswordUrl);
		Response response = target.request().header(HttpHeaders.AUTHORIZATION, token)
				.put(Entity.entity(password, MediaType.APPLICATION_JSON_TYPE));
		ResponseUtil.checkResponse(usersUserIdPasswordUrl, response);
		return response.getStatus();
	}
	
	public static void updatePasswordByUserName(String harbor, String token, String userName, String oldPassword, String newPassword) {
		JSONArray users = HarborUtil.getUsers(harbor, token, userName);
		HarborUtil.updatePasswordByUserId(harbor, token, users.getJSONObject(0).getLong("user_id"), oldPassword, newPassword);
			
	}
	
	/*
	 * @Parameter username : could be null
	 */
	public static JSONArray getUsers(String harbor, String token, String username) {
		// url		
		String usersUrl = MessageFormat.format(HarborUtil.USERSURLTEMPLATE, harbor);
		
		WebTarget target = ClientBuilder.newClient().target(usersUrl);
		Response response = target.queryParam("username", username).request()
				.header(HttpHeaders.AUTHORIZATION, token).get();
		String string = response.readEntity(String.class);
		return new JSONArray(string);		
	}
	
	/*
	 * @Param harbor 	: ip:port	
	 * @Param UserDTO	: {userName, userCode, password}	
	 */
	public static Response addUser(String harbor, String token, UserDTO userDTO) {
		// url
		String usersUrl = MessageFormat.format(HarborUtil.USERSURLTEMPLATE, harbor);
		
		// post body
		Map<String, String> user = new TreeMap<String, String>();
		user.put("username", userDTO.getUserCode());
		user.put("email", userDTO.getUserCode() + "@163.com");	// user1@163.com
		user.put("password", userDTO.getPassword());
		user.put("realname", userDTO.getUserName());		
		WebTarget target = ClientBuilder.newClient().target(usersUrl);
		Response response = target.request().header(HttpHeaders.AUTHORIZATION, token)
				.post(Entity.entity(user, MediaType.APPLICATION_JSON_TYPE));		
		return response;
	}
	
	public static void deleteUser(String harbor, String token, Long userId) {
		// url
		String usersUserIdUrl = MessageFormat.format(HarborUtil.USERSUSERIDURLTEMPLATE, harbor, userId);
		
		WebTarget target = ClientBuilder.newClient().target(usersUserIdUrl);
		Response response = target.request().header(HttpHeaders.AUTHORIZATION, token)
				.delete();
		ResponseUtil.checkResponse(usersUserIdUrl, response);
		
	}
	
	public static void deleteUserByName(String harbor, String token, String userName) {
		// get userId by userCode
		JSONArray users = HarborUtil.getUsers(harbor, token, userName);
		if(null != users && users.length() != 0) {
			Long userId = users.getJSONObject(0).getLong("user_id");
			HarborUtil.deleteUser(harbor, token, userId);
		}		
	}
	
	/*
	 * @Param projectName :	required = false
	 */
	public static JSONArray getProjects(String harbor, String token, String projectName) {		
		// url
		String projectsUrl = MessageFormat.format(HarborUtil.PROJECTSURLTEMPLATE, harbor);	
		
		WebTarget target = ClientBuilder.newClient().target(projectsUrl);
		Response response = target.queryParam("project_name", projectName).request()
				.header(HttpHeaders.AUTHORIZATION, token).get();
		ResponseUtil.checkResponse(projectsUrl, response);		 
		return new JSONArray(response.readEntity(String.class));
	}
	
	public static void createProject(String harbor, String token, String projectName, Integer isPublic) {
		// url
		String projectsUrl = MessageFormat.format(HarborUtil.PROJECTSURLTEMPLATE, harbor);
		
		// post body
		Map<String, Object> project = new TreeMap<>();
		project.put("project_name", projectName);
		project.put("public", isPublic);
		
		WebTarget target = ClientBuilder.newClient().target(projectsUrl);
		Response response = target.request().header(HttpHeaders.AUTHORIZATION, token)
				.post(Entity.entity(project, MediaType.APPLICATION_JSON_TYPE));
		ResponseUtil.checkResponse(projectsUrl, response);
	}
	
	public static void deleteProjectById(String harbor, String token, Long projectId) {
		// url
		String projectsProjectIdUrl = MessageFormat.format(HarborUtil.PROJECTSPROJECTIDURLTEMPLATE, harbor, projectId);
		
		WebTarget target = ClientBuilder.newClient().target(projectsProjectIdUrl);
		target.request().header(HttpHeaders.AUTHORIZATION, token)
				.delete();		
	}
	
	public static void deleteProjectByName(String harbor, String token, String projectName) {
				
		JSONArray projects = HarborUtil.getProjects(harbor, token, projectName);
		
		for(int i = 0; i < projects.length(); i++) {
			if(projectName.equals(projects.getJSONObject(i).getString("name"))) {
				HarborUtil.deleteProjectById(harbor, token, projects.getJSONObject(i).getLong("project_id"));
				break;
			}
		}
		
	}
	
	/*
	 * @Param targetName : could be null
	 */
	public static JSONArray getTargets(String harbor, String token, String targetName) {
		JSONArray jsonArray = null;
		try {
			String targetsUrl = MessageFormat.format(HarborUtil.TARGETSURLTEMPLATE, harbor);
			
			WebTarget target = ClientBuilder.newClient().target(targetsUrl);
			Response response = target.queryParam("name", targetName).request()
					.header(HttpHeaders.AUTHORIZATION, token).get();
			ResponseUtil.checkResponse(targetsUrl, response);		 
			jsonArray = new JSONArray(response.readEntity(String.class));
		} catch (Exception e) {
			logger.error("HarborUtil.getTargets() 出现异常!");
		} 
		return jsonArray;
	}
	
	/*
	 * @Param projectId				required = false
	 * @Param replicationName		required = false
	 */
	public static JSONArray getPoliciesReplications(String harbor, String token, Long projectId, String replicationName) {
		// url
		String policiesReplicationUrl = MessageFormat.format(HarborUtil.POLICIESREPLICATIONURLTEMPLATE, harbor);
		WebTarget target = ClientBuilder.newClient().target(policiesReplicationUrl);
		Response response = target.queryParam("project_id", projectId).queryParam("name", replicationName)
				.request().header(HttpHeaders.AUTHORIZATION, token).get();				
		ResponseUtil.checkResponse(policiesReplicationUrl, response);
		return new JSONArray(response.readEntity(String.class));
	}
	
	
	public static void createPoliciesReplication(String harbor, String token, Long projectId, Long targetId, String replicationName) {
		// url
		String policiesReplicationUrl = MessageFormat.format(HarborUtil.POLICIESREPLICATIONURLTEMPLATE, harbor);
		
		// post body
		Map<String, Object> replication = new TreeMap<>();
		replication.put("project_id", projectId);
		replication.put("target_id", targetId);
		replication.put("name", replicationName);
		
		WebTarget target = ClientBuilder.newClient().target(policiesReplicationUrl);
		Response response = target.request().header(HttpHeaders.AUTHORIZATION, token)
				.post(Entity.entity(replication, MediaType.APPLICATION_JSON_TYPE));
		ResponseUtil.checkResponse(policiesReplicationUrl, response);
	}
	
	public static void enableOrDisablePoliciesReplication(String harbor, String token, Long replicationId, Integer enabled) {
		// url
		String policiesReplicationIdEnablementUrl = MessageFormat.format(HarborUtil.POLICIESREPLICATIONIDENABLEMENTURLTEMPLATE, harbor, replicationId);
		
		// put body
		Map<String, Object> enablement = new TreeMap<>();
		enablement.put("enabled", enabled);
		
		WebTarget target = ClientBuilder.newClient().target(policiesReplicationIdEnablementUrl);
		Response response = target.request().header(HttpHeaders.AUTHORIZATION, token)
				.put(Entity.entity(enablement, MediaType.APPLICATION_JSON_TYPE));
		ResponseUtil.checkResponse(policiesReplicationIdEnablementUrl, response);
	}

	public static Response getRepositories(String harbor, String token, Long projectId, Integer pageNum,
			Integer pageSize) {
		String repositoriesUrl = MessageFormat.format(HarborUtil.REPOSITORIESURLTEMPLATE, harbor);
		WebTarget target = ClientBuilder.newClient().target(repositoriesUrl);
		Response response = target.queryParam("project_id", projectId).queryParam("page", pageNum)
				.queryParam("page_size", pageSize).request().header(HttpHeaders.AUTHORIZATION, token).get();
		ResponseUtil.checkResponse(repositoriesUrl, response);
		return response;
	}

	public static JSONArray getTags(String harbor, String token, String repository) {
		String repositoriesTagsUrl = MessageFormat.format(HarborUtil.REPOSITORIESTAGSURLTEMPLATE, harbor);
		WebTarget target = ClientBuilder.newClient().target(repositoriesTagsUrl);
		Response response = target.queryParam("repo_name", repository)
				.request().header(HttpHeaders.AUTHORIZATION, token).get();
		ResponseUtil.checkResponse(repositoriesTagsUrl, response);
		return new JSONArray(response.readEntity(String.class));		
	}		
	
}
